All files / Bandstand/src/app/api/bands/[id] route.ts

0% Statements 0/44
0% Branches 0/1
0% Functions 0/1
0% Lines 0/44

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45                                                                                         
export const dynamic = 'force-dynamic'

import {z} from 'zod'
import {prisma} from '@/lib/db'
import {requireOwner} from '@/lib/guard'
import {Host} from '@/lib/band-fields'
import {route} from '@/lib/route'

const Body = z.object({domains: z.array(Host).max(10)})

/**
 * The web addresses that belong to a band (owner only: each one also needs
 * DNS, a proxy route and, for Google sign-in, a redirect URI).
 */
export const PUT = route(
  async (req: Request, {params}: {params: {id: string}}) => {
    await requireOwner()
    const parsed = Body.safeParse(await req.json())
    if (!parsed.success)
      return Response.json(
        {error: 'One of those isn’t a web address.'},
        {status: 400},
      )
    const band = await prisma.band.findUnique({where: {id: params.id}})
    if (!band) return new Response('Not Found', {status: 404})
    const hosts = [...new Set(parsed.data.domains)]
    const taken = await prisma.bandDomain.findFirst({
      where: {host: {in: hosts}, bandId: {not: band.id}},
      include: {band: {select: {name: true}}},
    })
    if (taken)
      return Response.json(
        {error: `${taken.host} already belongs to ${taken.band.name}.`},
        {status: 409},
      )
    await prisma.$transaction([
      prisma.bandDomain.deleteMany({where: {bandId: band.id}}),
      prisma.bandDomain.createMany({
        data: hosts.map((host) => ({host, bandId: band.id})),
      }),
    ])
    return new Response(null, {status: 204})
  },
)